package service

import (
	"encoding/base64"
	"errors"
	"fmt"
	"github.com/go-admin-team/go-admin-core/sdk/service"
	"github.com/google/uuid"
	"strconv"
	"time"
	"vrcm/src/vrcm/app/admin/models/live_schedule"
	"vrcm/src/vrcm/app/admin/models/monitor"
	shareModel "vrcm/src/vrcm/app/admin/models/share"
	liveDto "vrcm/src/vrcm/app/admin/service/dto/live_schedule"
	"vrcm/src/vrcm/app/admin/service/dto/monitor"
	vrcDto "vrcm/src/vrcm/app/admin/service/dto/vrc"
	liveService "vrcm/src/vrcm/app/admin/service/live_schedule"
	hubService "vrcm/src/vrcm/app/admin/service/stream_hub"
	vrcService "vrcm/src/vrcm/app/admin/service/vrc"
	cDto "vrcm/src/vrcm/common/dto"
	"vrcm/src/vrcm/common/utils"
)

var templateMap = map[int]int{
	1: 1,
	2: 2,
	3: 4,
	4: 9,
	5: 16,
	6: 41,
	7: 51,
	8: 71,
}

var numMap = map[int]int{
	1: 1,
	2: 2,
	3: 4,
	4: 9,
	5: 16,
	6: 4,
	7: 5,
	8: 7,
}

type MonitorBasic struct {
	service.Service
}

// GetPage 获取MonitorBasic列表
func (e *MonitorBasic) GetPage(c *dto.MonitorBasicGetPageReq, list *[]monitor.MonitorBasic, count *int64) error {
	var err error
	var data monitor.MonitorBasic

	db := e.Orm.Model(&data).
		Scopes(
			cDto.MakeCondition(c.GetNeedSearch()),
			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
		)
	if len(c.BindId) > 0 {
		db.Where("bind_id=?", c.BindId)
	}
	err = db.Find(list).Limit(-1).Offset(-1).
		Count(count).Error
	if err != nil {
		e.Log.Errorf("MonitorBasicService GetPage error:%s \r\n", err)
		return err
	}
	configIds := make([]int, 0, 5)
	for _, v := range *list {
		v := v
		configIds = append(configIds, v.Id)
	}
	configs := make([]monitor.MonitorConfig, 0, 5)
	err = e.Orm.Model(&monitor.MonitorConfig{}).Where("basic_id in ?", configIds).Find(&configs).Error
	if err != nil {
		e.Log.Errorf("get MonitorConfig error:%s \r\n", err)
		return err
	}

	configMap := make(map[int64][]monitor.MonitorConfig)
	for _, v := range configs {
		v := v
		t, ok := configMap[v.BasicId]
		if !ok {
			t = make([]monitor.MonitorConfig, 0, 5)
		}
		t = append(t, v)
		configMap[v.BasicId] = t
	}
	for k, v := range *list {
		v := v
		configs := configMap[int64(v.Id)]
		*(&(*list)[k].MonitorConfigs) = configs
	}
	return nil
}

// Get 获取MonitorBasic对象
func (e *MonitorBasic) Get(d *dto.MonitorBasicGetReq) (*monitor.MonitorModel, error) {
	var model monitor.MonitorModel
	var data monitor.MonitorBasic
	err := e.Orm.Model(&data).Where("id=?", d.GetId()).Find(&data).Error
	if err != nil {
		e.Log.Errorf("db error:%s", err)
		return &model, err
	}
	model.MonitorBasic = data
	configs := make([]monitor.MonitorConfig, 0, 5)
	err = e.Orm.Model(&monitor.MonitorConfig{}).Where("basic_id=?", d.GetId()).Find(&configs).Error
	if err != nil {
		e.Log.Errorf("db error:%s", err)
		return &model, err
	}
	model.MonitorConfigs = configs
	return &model, nil
}

func (e *MonitorBasic) GetMonitorConfig(d *dto.MonitorConfigGetReq) (*monitor.MonitorConfig, error) {
	var data monitor.MonitorConfig
	err := e.Orm.Model(&data).Where("id=?", d.Id).Find(&data).Error
	if err != nil {
		e.Log.Errorf("get MonitorConfig:%s", err)
		return &data, err
	}
	return &data, nil
}

// Insert 创建MonitorBasic对象
func (e *MonitorBasic) Insert(c *dto.MonitorBasicInsertReq) error {
	tx := e.Orm.Begin()
	defer func() {
		if r := recover(); r != nil {
			e.Log.Errorf("创建监控任务:%s", r)
			tx.Rollback()
		}
	}()

	var err error
	var data monitor.MonitorBasic
	c.Generate(&data)
	err = tx.Create(&data).Error
	if err != nil {
		tx.Rollback()
		e.Log.Errorf("创建监控任务:%s \r\n", err)
		return err
	}

	tx.Commit()
	return nil
}

// SaveMonitor 修改MonitorBasic对象
func (e *MonitorBasic) SaveMonitor(c *dto.MonitorBasicUpdateReq) error {
	tx := e.Orm.Begin()
	defer func() {
		if r := recover(); r != nil {
			e.Log.Errorf("创建监控任务:%s", r)
			tx.Rollback()
		}
	}()

	for _, char := range c.MonitorBasic.MonitorName {
		if char >= 0x1F600 && char <= 0x1F64F {
			return errors.New("不允许输入特殊字符")
		}
	}
	sourceService := liveService.SourceBasicService{}
	sourceService.Log = e.Log
	sourceService.Orm = e.Orm
	var vrcService vrcService.VrcService
	vrcService.Log = e.Log
	var err error
	var data = monitor.MonitorBasic{}
	err = tx.Model(&monitor.MonitorBasic{}).Where("id=?", c.MonitorBasic.Id).Find(&data).Error
	if err != nil {
		tx.Rollback()
		e.Log.Errorf("get MonitorBasic:%s \r\n", err)
		return err
	}

	//如果是修改模版则需要把原来的视窗配置删除
	if data.Id > 0 && data.TemplateType != c.MonitorBasic.TemplateType {
		err = tx.Model(&monitor.MonitorConfig{}).Where("basic_id=?", data.Id).Delete(&monitor.MonitorConfig{}).Error
		if err != nil {
			tx.Rollback()
			e.Log.Errorf("delete MonitorConfig:%s ", err)
			return err
		}
	}

	c.Generate(&data)
	db := tx.Save(&data)
	if err = db.Error; err != nil {
		tx.Rollback()
		e.Log.Errorf("Save  MonitorBasic error:%s ", err)
		return err
	}

	now := time.Now().Unix()

	//存储自定义信源
	sourceIds := make([]int64, 0, 5)
	if len(c.Configs) > 0 {
		for k, v := range c.Configs {
			v := v
			if v.Id <= 0 {
				*(&c.Configs[k].CreateTime) = now
			} else {
				*(&c.Configs[k].UpdateTime) = now
			}
			if v.TransRecordId < 0 {
				*(&c.Configs[k].TransRecordId) = 0
			}
			*(&c.Configs[k].BasicId) = int64(data.Id)
			if v.SourceId <= 0 {
				continue
			}

			udp, err := e.ProcessUdp(v)
			if err != nil {
				tx.Rollback()
				e.Log.Errorf("获取udp地址失败:%s \r\n", err)
				return err
			}
			e.Log.Trace(c.Configs[k].SourceId)
			*(&c.Configs[k].StreamUrl) = udp
			*(&c.Configs[k].IsConfig) = 1
			if v.InputMode == 2 {
				sourceIds = append(sourceIds, v.SourceId)
			}
		}
		err = tx.Save(&c.Configs).Error
		if err != nil {
			tx.Rollback()
			e.Log.Errorf("save MonitorConfig:%s ", err)
			return err
		}
	}

	var basic monitor.MonitorBasic
	err = tx.Model(&monitor.MonitorBasic{}).Where("id=?", data.Id).Find(&basic).Error
	if err != nil {
		tx.Rollback()
		e.Log.Errorf("get MonitorBasic:%s \r\n", err)
		return err
	}

	configs := make([]monitor.MonitorConfig, 0, 5)
	//重新获取视图配置信息
	err = tx.Model(&monitor.MonitorConfig{}).Where("basic_id=?", basic.Id).Find(&configs).Error
	if err != nil {
		tx.Rollback()
		e.Log.Errorf("获取视图配置失败:%s \r\n", err)
		return err
	}
	//创建或者更新房间
	inputs := make([]vrcDto.InputSource, 0, 5)
	for _, v := range configs {
		input := vrcDto.InputSource{}
		input.Protocol = "udp"
		input.Type = "push"
		input.Name = v.ViewName
		input.Position = v.ViewNo
		input.PushAddress = v.StreamUrl
		inputs = append(inputs, input)
	}

	res, err := vrcService.SaveRoom(&vrcDto.SaveRoomReq{Title: basic.MonitorName, TenantId: basic.TenantId, Template: templateMap[basic.TemplateType], Poster: basic.VideoPadding, ServiceType: "21", RoomType: "1", EventId: basic.EventId, InputSources: inputs, Id: basic.TaskId})
	if err != nil {
		tx.Rollback()
		e.Log.Errorf("保存监看配置失败:%s", err)
		return err
	}
	//更新监看任务id
	if res != nil {
		params := make(map[string]interface{})
		params["task_id"] = res.Id
		params["event_id"] = res.EventId
		params["update_time"] = now
		err = tx.Model(&monitor.MonitorBasic{}).Where("id=?", basic.Id).Updates(params).Error
		if err != nil {
			tx.Rollback()
			e.Log.Errorf("更新监看配置失败:%s", err)
			return err
		}
	}

	if c.MonitorBasic.Id > 0 && basic.MonitorState == 1 {
		for _, v := range sourceIds {
			err = sourceService.StartSource(&liveDto.StartSourceReq{Id: int(v), TenantId: c.MonitorBasic.TenantId})
			if err != nil {
				tx.Rollback()
				e.Log.Errorf("开启自定义信源失败:%s", err)
				return err
			}
		}

		err = vrcService.RestartRoom(&vrcDto.StartRoomReq{TenantId: basic.TenantId, EventId: basic.EventId})
		if err != nil {
			tx.Rollback()
			e.Log.Errorf("重启监看配置失败:%s", err)
			return err
		}
	}
	tx.Commit()
	c.MonitorBasic.Id = basic.Id
	return nil
}

func (e *MonitorBasic) SaveMonitorConfig(c *dto.MonitorBasicConfigReq) error {
	tx := e.Orm.Begin()
	defer func() {
		if r := recover(); r != nil {
			e.Log.Errorf("保存监看配置失败:%s", r)
			tx.Rollback()
		}
	}()

	var vrcService vrcService.VrcService
	vrcService.Log = e.Log
	//获取监看基本信息
	var basic monitor.MonitorBasic
	err := tx.Model(&monitor.MonitorBasic{}).Where("id=?", c.BasicId).Find(&basic).Error
	if err != nil {
		tx.Rollback()
		e.Log.Errorf("获取监看配置失败:%s \r\n", err)
		return err
	}
	if basic.MonitorState == 1 {
		return errors.New("监看任务已启用！")
	}
	//保存视图配置
	now := time.Now().Unix()
	data := monitor.MonitorConfig{}
	data.Id = c.Id
	data.TenantId = c.TenantId
	data.BasicId = c.BasicId
	data.ViewNo = c.ViewNo
	data.ViewName = c.ViewName
	data.InputMode = c.InputMode
	data.SourceId = c.SourceId
	data.StreamType = c.StreamType
	data.SourceType = c.SourceType
	data.ActiveItem = c.ActiveItem
	data.IsConfig = 1
	data.UpdateTime = now
	if c.Id <= 0 {
		data.CreateTime = now
	}
	udp, err := e.ProcessUdp(data)
	if err != nil {
		tx.Rollback()
		e.Log.Errorf("获取udp地址失败:%s \r\n", err)
		return err
	}
	data.StreamUrl = udp
	err = tx.Save(&data).Error
	if err != nil {
		tx.Rollback()
		e.Log.Errorf("保存监看配置失败:%s \r\n", err)
		return err
	}

	//重新获取视图配置信息
	configs := make([]monitor.MonitorConfig, 0, 5)
	err = tx.Model(&monitor.MonitorConfig{}).Where("basic_id=?", c.BasicId).Find(&configs).Error
	if err != nil {
		tx.Rollback()
		e.Log.Errorf("获取视图配置失败:%s \r\n", err)
		return err
	}

	inputs := make([]vrcDto.InputSource, 0, 5)
	for _, v := range configs {
		input := vrcDto.InputSource{}
		input.Protocol = "udp"
		input.Type = "push"
		input.Name = v.ViewName
		input.Position = v.ViewNo
		input.PushAddress = v.StreamUrl
		inputs = append(inputs, input)
	}
	//创建或者更新房间
	res, err := vrcService.SaveRoom(&vrcDto.SaveRoomReq{Title: basic.MonitorName, TenantId: c.TenantId, Template: templateMap[basic.TemplateType], Poster: basic.VideoPadding, ServiceType: "21", RoomType: "1", EventId: basic.EventId, InputSources: inputs, Id: basic.TaskId})
	if err != nil {
		tx.Rollback()
		e.Log.Errorf("保存监看配置失败:%s", err)
		return err
	}
	//更新监看任务id
	if res != nil {
		params := make(map[string]interface{})
		params["task_id"] = res.Id
		params["event_id"] = res.EventId
		params["update_time"] = now
		err = tx.Model(&monitor.MonitorBasic{}).Where("id=?", basic.Id).Updates(params).Error
		if err != nil {
			tx.Rollback()
			e.Log.Errorf("更新监看配置失败:%s", err)
			return err
		}
	}
	c.Id = data.Id
	tx.Commit()
	return nil
}

func (e *MonitorBasic) ProcessUdp(config monitor.MonitorConfig) (string, error) {
	liveService := liveService.SourceBasicService{}
	liveService.Log = e.Log
	liveService.Orm = e.Orm
	//获取信源信息
	res, err := liveService.Get(&liveDto.SourceBasicGetReq{Id: int(config.SourceId)})
	if err != nil {
		e.Log.Errorf("获取信源详情失败:%s \r\n", err)
		return "", err
	}
	detailMap := make(map[int]live_schedule.SourceDetail)
	for _, v := range res.SourceDetails {
		v := v
		detailMap[v.SourceDetail.UrlType] = v.SourceDetail
	}
	transMap := make(map[int]live_schedule.SourceTemplateModel)
	for _, v := range res.TransCodeTasks {
		v := v
		transMap[v.SourceTemplate.Id] = v
	}
	e.Log.Trace("获取信源的数据：", res.SourceBasic.OutUdpUrl)

	//自动监看
	udp := ""
	//原始流
	if config.StreamType == 1 {
		if config.ActiveItem == 5 {
			udp = res.SourceBasic.OutUdpUrl
		} else {
			detail := detailMap[config.ActiveItem]
			udp = detail.InUdpUrl
		}
	} else {
		transBasic := transMap[config.TransRecordId]
		if config.ActiveItem == 5 {
			udp = transBasic.SourceTemplate.TransCodeOutputAddress
		} else {
			for _, v := range transBasic.TransCodeTasks {
				if v.TransCodeTask.UrlType == config.ActiveItem {
					udp = v.TransCodeTask.OutUdpUrl
				}
			}
		}
	}

	//udp信源进行特殊处理
	if res.SourceBasic.ProtocolType == 5 && res.SourceBasic.SourceState == 2 {
		udp = ""
	}
	e.Log.Trace("获取到的udp地址：", udp)
	return udp, nil
}

// Remove 删除MonitorBasic
func (e *MonitorBasic) Remove(d *dto.MonitorBasicDeleteReq) error {
	tx := e.Orm.Begin()
	defer func() {
		if r := recover(); r != nil {
			e.Log.Errorf("保存监看配置失败:%s", r)
			tx.Rollback()
		}
	}()
	var vrcService vrcService.VrcService
	vrcService.Log = e.Log

	s := liveService.SourceBasicService{}
	s.Log = e.Log
	s.Orm = e.Orm
	hub := hubService.StreamHubService{}
	hub.Log = e.Log

	basics := make([]monitor.MonitorBasic, 0, 5)
	err := tx.Model(&monitor.MonitorBasic{}).Where("id in ?", d.Ids).Find(&basics).Error
	if err != nil {
		tx.Rollback()
		e.Log.Errorf("获取监看任务失败: %s", err)
		return err
	}

	for _, v := range basics {
		if v.MonitorState == 1 {
			tx.Commit()
			return errors.New("监看任务已启用！")
		}
	}

	for _, v := range basics {
		if len(v.EventId) > 0 {
			err = vrcService.DeleteRoom1(&vrcDto.DeleteRoomReq{TenantId: v.TenantId, EventId: v.EventId})
			if err != nil {
				tx.Rollback()
				e.Log.Errorf("删除房间失败: %s", err)
				return err
			}
		}

	}

	sourceIds := make([]int, 0, 5)
	err = tx.Model(&monitor.MonitorConfig{}).Select("source_id").Where("basic_id in ? and source_id>0 and input_mode=2", d.Ids).Find(&sourceIds).Error
	if err != nil {
		tx.Rollback()
		e.Log.Errorf("获取监看基本配置失败:%s", err)
		return err
	}
	err = s.Remove(&liveDto.SourceBasicDeleteReq{Ids: sourceIds})
	if err != nil {
		tx.Rollback()
		e.Log.Errorf("删除自定义信源失败:%s", err)
		return err
	}
	err = tx.Model(&monitor.MonitorBasic{}).Where("id in ?", d.Ids).Delete(&monitor.MonitorBasic{}).Error
	if err != nil {
		tx.Rollback()
		e.Log.Errorf("删除监看任务失败: %s", err)
		return err
	}
	err = tx.Model(&monitor.MonitorConfig{}).Where("basic_id in ?", d.Ids).Delete(&monitor.MonitorConfig{}).Error
	if err != nil {
		tx.Rollback()
		e.Log.Errorf("删除监看详情失败: %s", err)
		return err
	}

	tx.Commit()
	return nil
}

func (e *MonitorBasic) StartMonitor(d *dto.MonitorStartReq) error {
	var vrcService vrcService.VrcService
	vrcService.Log = e.Log
	s := liveService.SourceBasicService{}
	s.Log = e.Log
	s.Orm = e.Orm
	hub := hubService.StreamHubService{}
	hub.Log = e.Log

	var basic monitor.MonitorBasic
	err := e.Orm.Model(&monitor.MonitorBasic{}).Where("event_id=?", d.EventId).Find(&basic).Error
	if err != nil {
		e.Log.Errorf("获取监看基本信息失败:%s", err)
		return err
	}
	sourceIds := make([]int, 0, 5)
	err = e.Orm.Model(&monitor.MonitorConfig{}).Select("source_id").Where("basic_id=? and source_id>0", basic.Id).Find(&sourceIds).Error
	if err != nil {
		e.Log.Errorf("获取监看基本配置失败:%s", err)
		return err
	}

	sourceMap, err := s.GetCustomSource(sourceIds)
	if err != nil {
		e.Log.Errorf("获取自定义信源失败:%s", err)
		return err
	}
	for _, v := range sourceMap {
		if v.Kind == 2 {
			err = s.StartSource(&liveDto.StartSourceReq{Id: v.Id, TenantId: v.TenantId})
			if err != nil {
				e.Log.Errorf("启用信源失败:%s", err)
				return err
			}
		}
	}
	err = vrcService.StartRoom(&vrcDto.StartRoomReq{TenantId: d.TenantId, EventId: d.EventId})
	if err != nil {
		e.Log.Errorf("启用监看任务失败:%s", err)
		return err
	}
	now := time.Now().Unix()
	params := make(map[string]interface{})
	params["monitor_state"] = 1
	params["update_time"] = now

	err = e.Orm.Model(&monitor.MonitorBasic{}).Where("tenant_id=? and event_id=?", d.TenantId, d.EventId).Updates(params).Error
	if err != nil {
		e.Log.Errorf("启用监看配置失败:%s", err)
		return err
	}
	return nil
}

func (e *MonitorBasic) StopMonitor(d *dto.MonitorStopReq) error {
	var vrcService vrcService.VrcService
	vrcService.Log = e.Log
	s := liveService.SourceBasicService{}
	s.Log = e.Log
	s.Orm = e.Orm
	hub := hubService.StreamHubService{}
	hub.Log = e.Log
	var basic monitor.MonitorBasic
	err := e.Orm.Model(&monitor.MonitorBasic{}).Where("event_id=?", d.EventId).Find(&basic).Error
	if err != nil {
		e.Log.Errorf("获取监看基本信息失败:%s", err)
		return err
	}
	sourceIds := make([]int, 0, 5)
	err = e.Orm.Model(&monitor.MonitorConfig{}).Select("source_id").Where("basic_id=? and source_id>0", basic.Id).Find(&sourceIds).Error
	if err != nil {
		e.Log.Errorf("获取监看基本配置失败:%s", err)
		return err
	}

	sourceMap, err := s.GetCustomSource(sourceIds)
	if err != nil {
		e.Log.Errorf("获取自定义信源失败:%s", err)
		return err
	}
	for _, v := range sourceMap {
		if v.Kind == 2 {
			err = s.StopSource(&liveDto.StopSourceReq{Id: v.Id, TenantId: v.TenantId, TaskId: v.TaskId})
			if err != nil {
				e.Log.Errorf("停用信源失败:%s", err)
				return err
			}
		}
	}
	err = vrcService.StopRoom(&vrcDto.StopRoomReq{TenantId: d.TenantId, EventId: d.EventId})
	if err != nil {
		e.Log.Errorf("停用监看任务失败:%s", err)
		return err
	}
	now := time.Now().Unix()
	params := make(map[string]interface{})
	params["monitor_state"] = 2
	params["update_time"] = now
	err = e.Orm.Model(&monitor.MonitorBasic{}).Where("tenant_id=? and event_id=?", d.TenantId, d.EventId).Updates(params).Error
	if err != nil {
		e.Log.Errorf("停用监看配置失败:%s", err)
		return err
	}
	return nil
}

func (e *MonitorBasic) ResetMonitorConfig(c *dto.RestReq) error {
	tx := e.Orm.Begin()
	defer func() {
		if r := recover(); r != nil {
			e.Log.Errorf("保存监看配置失败:%s", r)
			tx.Rollback()
		}
	}()

	//now := time.Now().Unix()
	var config monitor.MonitorConfig
	err := tx.Model(&monitor.MonitorConfig{}).Where("id=?", c.Id).Find(&config).Error
	if err != nil {
		tx.Rollback()
		e.Log.Errorf("获取监看配置失败:%s", err)
		return err
	}

	//获取监看基本信息
	var basic monitor.MonitorBasic
	err = tx.Model(&monitor.MonitorBasic{}).Where("id=?", config.BasicId).Find(&basic).Error
	if err != nil {
		tx.Rollback()
		e.Log.Errorf("获取监看配置失败:%s \r\n", err)
		return err
	}
	if basic.MonitorState == 1 {
		return errors.New("监看任务已启用！")
	}

	//删除
	err = tx.Model(&monitor.MonitorConfig{}).Where("id=?", c.Id).Delete(&monitor.MonitorConfig{}).Error
	if err != nil {
		tx.Rollback()
		e.Log.Errorf("删除监看配置失败:%s", err)
		return err
	}

	configs := make([]monitor.MonitorConfig, 0, 5)
	//重新获取视图信息
	err = tx.Model(&monitor.MonitorConfig{}).Where("basic_id=?", config.BasicId).Find(&configs).Error
	if err != nil {
		tx.Rollback()
		e.Log.Errorf("获取监看配置失败:%sn", err)
		return err
	}
	var vrcService vrcService.VrcService
	vrcService.Log = e.Log

	inputs := make([]vrcDto.InputSource, 0, 5)
	for _, v := range configs {
		input := vrcDto.InputSource{}
		input.Protocol = "udp"
		input.Type = "push"
		input.Name = v.ViewName
		input.Position = v.ViewNo
		input.PullAddress = v.StreamUrl
		inputs = append(inputs, input)
	}
	//创建或者更新房间
	_, err = vrcService.SaveRoom(&vrcDto.SaveRoomReq{Title: basic.MonitorName, TenantId: basic.TenantId, Template: templateMap[basic.TemplateType], Poster: basic.VideoPadding, ServiceType: "21", RoomType: "1", EventId: basic.EventId, InputSources: inputs, Id: basic.TaskId})
	if err != nil {
		tx.Rollback()
		e.Log.Errorf("保存监看配置失败:%s", err)
		return err
	}
	////更新监看任务id
	//if res != nil {
	//	params := make(map[string]interface{})
	//	params["task_id"] = res.Id
	//	params["event_id"] = res.EventId
	//	params["update_time"] = now
	//	err = tx.Model(&monitor.MonitorBasic{}).Where("id=?", basic.Id).Updates(params).Error
	//	if err != nil {
	//		tx.Rollback()
	//		e.Log.Errorf("更新监看配置失败:%s", err)
	//		return err
	//	}
	//}
	c.Id = basic.Id
	tx.Commit()
	return nil
}

func (e *MonitorBasic) CreateShare(c *dto.CreateShareReq) error {
	now := time.Now().Unix()
	share := shareModel.ShareRecord{}
	share.TenantId = c.TenantId
	share.BindId = strconv.Itoa(c.Id)
	share.IsPassword = c.IsPassword
	share.Password = utils.CreateRandomString(4)
	share.ShareType = 1
	share.ExpireTime = c.ExpireTime
	share.CreateTime = now
	share.UpdateTime = now
	share.ObjectUuid = uuid.New().String()
	e.Log.Trace("密码：", share.Password)
	passwordEncryption, err := utils.RsaEncodeByPublic([]byte(share.Password), utils.SharePublicKey)
	if err != nil {
		e.Log.Errorf("加密失败:%s", err)
		return err
	}
	accessKeyBase64 := base64.StdEncoding.EncodeToString([]byte(passwordEncryption))
	if err != nil {
		e.Log.Errorf("加密失败:%s", err)
		return err
	}

	share.Password = accessKeyBase64
	err = e.Orm.Model(&shareModel.ShareRecord{}).Create(&share).Error
	if err != nil {
		e.Log.Errorf("创建分享失败:%s", err)
		return err
	}
	return nil
}
func (e *MonitorBasic) GetShareInfoByUuid(c *dto.GetShareInfoReq) (*monitor.MonitorModel, error) {
	shareInfo := &shareModel.ShareRecord{}
	basic := &monitor.MonitorModel{}
	err := e.Orm.Model(&shareModel.ShareRecord{}).Where("object_uuid=?", c.Uuid).Find(&shareInfo).Error
	if err != nil {
		e.Log.Errorf("获取分享失败:%s", err)
		return basic, err
	}
	fmt.Println(shareInfo)
	if shareInfo.CreateTime+shareInfo.ExpireTime < time.Now().Unix() && shareInfo.ExpireTime > 0 {
		e.Log.Errorf("获取分享失败:%s", "有效期已过")
		return basic, err
	}
	if shareInfo.IsPassword == 1 {
		b := utils.CheckPassword(c.Password, shareInfo.Password)
		if !b {
			return basic, errors.New("验证密码失败")
		}
	}
	id, _ := strconv.Atoi(shareInfo.BindId)
	basic, err = e.Get(&dto.MonitorBasicGetReq{Id: id})
	if err != nil {
		e.Log.Errorf("获取监看信息失败:%s", err)
		return basic, err
	}
	return basic, nil
}

func (e *MonitorBasic) GetByEventId(d *dto.MonitorBasicGetByEventIdReq) (*monitor.MonitorModel, error) {
	var model monitor.MonitorModel
	var data monitor.MonitorBasic
	sourceBasicService := liveService.SourceBasicService{}
	sourceBasicService.Orm = e.Orm
	sourceBasicService.Log = e.Log
	err := e.Orm.Model(&data).Where("event_id=?", d.EventId).Find(&data).Error
	if err != nil {
		e.Log.Errorf("db error:%s", err)
		return &model, err
	}
	model.MonitorBasic = data
	configs := make([]monitor.MonitorConfig, 0, 5)
	err = e.Orm.Model(&monitor.MonitorConfig{}).Where("basic_id=?", data.Id).Find(&configs).Error
	if err != nil {
		e.Log.Errorf("db error:%s", err)
		return &model, err
	}
	model.MonitorConfigs = configs
	sourceIds := make([]int64, 0, 4)
	for _, v := range configs {
		v := v
		sourceIds = append(sourceIds, v.SourceId)
	}
	res := make([]liveDto.SourceBasicGetRes, 0, 4)
	basics := make([]live_schedule.SourceBasic, 0, 4)
	err = e.Orm.Model(&live_schedule.SourceBasic{}).Where("id in ?", sourceIds).Find(&basics).Error
	if err != nil {
		e.Log.Errorf("get SourceBasic:%s", err)
		return &model, err
	}

	details := make([]live_schedule.SourceDetail, 0, 4)
	detailMap := make(map[int][]live_schedule.SourceDetailModel)
	err = e.Orm.Model(&live_schedule.SourceDetail{}).Where("source_id in ?", sourceIds).Find(&details).Error
	if err != nil {
		e.Log.Errorf("get SourceDetail:%s", err)
		return &model, err
	}
	for _, v := range details {
		v := v
		d, ok := detailMap[v.SourceId]
		if !ok {
			d = make([]live_schedule.SourceDetailModel, 0, 5)
		}
		m := live_schedule.SourceDetailModel{}
		m.SourceDetail = v
		d = append(d, m)
		detailMap[v.SourceId] = d
	}

	for _, v := range basics {
		v := v
		r := liveDto.SourceBasicGetRes{}
		r.SourceBasic = &v
		d := detailMap[v.Id]
		r.SourceDetails = d
		res = append(res, r)
	}
	for k, v := range configs {
		v := v
		for _, r := range res {
			for _, d := range r.SourceDetails {
				d := d
				if v.ActiveItem == 5 {
					if d.SourceDetail.UrlType == r.SourceBasic.ActiveItem {
						*(&configs[k].NodeId) = d.SourceDetail.NodeId
					}
				} else if d.SourceDetail.UrlType == v.ActiveItem {
					*(&configs[k].NodeId) = d.SourceDetail.NodeId
				}
			}
		}
	}

	return &model, nil
}
